//
// Created by Andrew Yang on 8/30/21.
//

#ifndef QI_SCANNER_H
#define QI_SCANNER_H

typedef enum {
    // Single-character tokens.
    TOKEN_LEFT_PAREN, TOKEN_RIGHT_PAREN,
    TOKEN_LEFT_BRACE, TOKEN_RIGHT_BRACE,
    TOKEN_COMMA, TOKEN_DOT, TOKEN_MINUS,
    TOKEN_PLUS, TOKEN_SEMICOLON, TOKEN_SLASH,
    TOKEN_STAR, TOKEN_COLON, TOKEN_LEFT_BRACKET,
    TOKEN_RIGHT_BRACKET, TOKEN_PERCENT,
    // One or two character tokens.
    TOKEN_BANG, TOKEN_BANG_EQUAL,
    TOKEN_EQUAL, TOKEN_EQUAL_EQUAL,
    TOKEN_GREATER, TOKEN_GREATER_EQUAL,
    TOKEN_LESS, TOKEN_LESS_EQUAL,
    TOKEN_PLUS_EQUAL, TOKEN_MINUS_EQUAL,
    TOKEN_PLUS_PLUS, TOKEN_MINUS_MINUS,
    // Literals.
    TOKEN_IDENTIFIER, TOKEN_STRING,
    TOKEN_DECIMAL, TOKEN_OCTAL,
    TOKEN_HEXADECIMAL, TOKEN_BINARY,
    // Keywords.
    TOKEN_AND, TOKEN_CLASS, TOKEN_ELSE, TOKEN_FALSE,
    TOKEN_FOR, TOKEN_FUN, TOKEN_IF, TOKEN_NIL, TOKEN_OR,
    TOKEN_RETURN, TOKEN_SUPER, TOKEN_THIS, TOKEN_TRUE,
    TOKEN_VAR, TOKEN_WHILE, TOKEN_CASE, TOKEN_DEFAULT,
    TOKEN_SWITCH, TOKEN_CONTINUE, TOKEN_BREAK,
    TOKEN_BITWISE_AND, TOKEN_BITWISE_OR, TOKEN_BITWISE_XOR,
    TOKEN_BITWISE_NOT, TOKEN_BITWISE_LEFT_SHIFT,
    TOKEN_BITWISE_RIGHT_SHIFT,

    TOKEN_NEWLINE, TOKEN_ERROR, TOKEN_EOF,
} TokenType;

typedef struct {
    TokenType type;
    const wchar_t* start;
    int length;
    int line;
} Token;

void initScanner(const wchar_t* source);
Token scanToken();

#endif //QI_SCANNER_H
